home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1996 March
/
EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso
/
earcd
/
faq
/
fds-310.lha
/
FindDesc11.lha
/
FindDesc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-27
|
7KB
|
201 lines
/*
** FindDesc.c 1.1 Public domain, written by Marcus Ohlström
**
** May be freely redistributed. You may use whatever part you want to
** in your own programs.
**
** This program is written using 100% ANSI-C. That means you can
** compile it with any c-compiler supporting the ANSI-standard, which
** most c-compilers do.
**
** In case of problems, or if you have any questions, e-mail me at
** marcus@karkis.canit.se and I will try to help you!
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define START_STR "@BEGIN USG_FILEDESC"
#define END_STR "@END USG_FILEDESC"
#define SHORT_END_STR "END:"
#define MAX_LEN 22 /* may NOT be smaller than strlen(START_STR) */
#define FALSE 0
#define TRUE 1
int main(int, char **);
int finddesc(FILE *, long int *, long int *);
void fprintfdesc(FILE *, FILE *, long int, long int);
int main(int argc, char **argv)
{
FILE *in = NULL, *out = stdout;
long int start, end;
int exitcode = 20;
if(argc == 2 || argc == 3)
{
if(NULL != (in = fopen(argv[1], "r")))
{
if(NULL != finddesc(in, &start, &end))
{
/* do not open out until we are sure an USG-desc exists */
if((3 == argc) && (NULL == (out = fopen(argv[2], "w"))))
{
fprintf(stderr, "Could not create \"%s\", using stdout instead.\n\n", argv[2]);
out = stdout;
}
fprintfdesc(in, out, start, end);
exitcode = 0; /* everything worked fine */
} else fprintf(stderr, "Could not find filedescription.\n");
} else fprintf(stderr, "Could not open \"%s\".\n", argv[1]);
} else fprintf(stderr, "Usage: %s infile [outfile]\n", argv[0]);
if(in != NULL) fclose(in);
if(out != stdout) fclose(out);
return(exitcode);
}
/*
* finddesc() requires 3 arguments:
*
* FILE *in should be a pointer to the file to read from
* long int *startptr will be set to point at the beginning of the description
* long int *endptr will be set to point at the end of the description
*
* finddesc() will return 0 if it fails and 1 if it succeeds
*/
int finddesc(FILE *in, long int *startptr, long int *endptr)
{
char *buffer, *pos = NULL, *tmp;
size_t size;
int success = FALSE;
int cnt;
if(NULL != (buffer = malloc(MAX_LEN + 1)))
{
buffer[MAX_LEN] = '\0';
/* while (we haven't found "@BEGIN FILEDESC") and (we do get some text) */
while((NULL == pos) && (NULL != (size = fread(buffer, 1, MAX_LEN, in))))
{
/* search through the whole buffer */
for(cnt = 0; cnt <= MAX_LEN; cnt += strlen(&buffer[cnt]) + 1)
{
/* did we found a match? */
if(NULL != (pos = strstr(&buffer[cnt], START_STR)))
break;
}
if(NULL == pos)
{
/* we haven't found any match, now check the last chars */
if(NULL != (tmp = strchr(&buffer[MAX_LEN+2-sizeof(START_STR)], '@')))
{
if(NULL == strncmp(tmp, START_STR, strlen(tmp)))
/* found something that can be a match! Rewind */
/* the FILE-pointer and read it again */
fseek(in, (long) 0-strlen(tmp), SEEK_CUR);
}
}
}
pos += strlen(START_STR);
while(isspace(*pos)) /* skip all whitespaces */
pos++;
fseek(in, 0-size+(pos-buffer), SEEK_CUR);
if(!feof(in))
{
*startptr = ftell(in);
pos = NULL;
/* while (we haven't found "@END FILEDESC") and (we do get some text) */
while((NULL == pos) && (NULL != (size = fread(buffer, 1, MAX_LEN, in))))
{
/* search through the whole buffer */
for(cnt = 0; cnt <= MAX_LEN; cnt += strlen(&buffer[cnt]) + 1)
{
/* did we found a match? */
if(NULL != (pos = strstr(&buffer[cnt], END_STR)))
break;
}
if(NULL == pos)
{
/* we haven't found any match, now check the last chars */
if(NULL != (tmp = strchr(&buffer[MAX_LEN+2-sizeof(END_STR)], '@')))
{
if(NULL == strncmp(tmp, END_STR, strlen(tmp)))
/* found something that can be a match! Rewind */
/* the FILE-pointer and read it again */
fseek(in, (long) 0-strlen(tmp), SEEK_CUR);
}
}
}
fseek(in, 0-size+(pos-buffer), SEEK_CUR);
if(!feof(in))
{
*endptr = ftell(in);
success = TRUE;
} else {
/* did not find "@END FILEDESC", search for "%END:" or "$END:" */
fseek(in, *startptr, SEEK_SET);
/* while we get some text */
while(NULL != fgets(buffer, MAX_LEN, in))
{
/* did we find "%END:" or "$END:" or did we not? */
if(NULL == strncmp(&buffer[1], SHORT_END_STR, 4) && (buffer[0] == '%' || buffer[0] == '$'))
break;
}
if(!feof(in))
{
/* set endposition, do not print anything after "?END:" */
fseek(in, (long) 5-strlen(buffer), SEEK_CUR);
*endptr = ftell(in);
success = TRUE;
}
}
}
free(buffer);
}
return(success);
}
/*
* fprintfdesc() requires 4 arguments:
*
* FILE *in a pointer to the file to read from
* FILE *out a pointer to the file to write to, or stdout
* long int start the startposition of the description, use with fseek()
* long int end the endposition of the description, use with fseek()
*
* fprintfdesc() does not return any value
*/
void fprintfdesc(FILE *in, FILE *out, long int start, long int end)
{
char *buffer;
size_t len = end-start;
if(buffer=malloc(len))
{
if(fseek(in, start, SEEK_SET) || NULL == (fread(buffer, 1, len, in)) || len > fwrite(buffer, 1, len, out))
fprintf(stderr, "An error has occurred, terminating.\n");
else
if(buffer[len-1] != '\n')
fputc('\n', out);
free(buffer);
}
}